/*
 * author      : 吴中勤
 * date        : 2018/8/18
 * description : SAP sdk
 */

package com.deepexi.adapter.sdk.sap;

import com.deepexi.adapter.common.HttpClientUtil;
import com.deepexi.adapter.common.exception.HttpNon200Exception;
import com.deepexi.adapter.common.sdk.RequestInfo;
import com.deepexi.adapter.sdk.sap.dto.bp.SapBPResponseBody;
import com.deepexi.adapter.sdk.sap.dto.bp.create.SapBPCreateRequestBody;
import com.deepexi.adapter.sdk.sap.dto.bp.extend.SapBPExtendRequestBody;
import com.deepexi.adapter.sdk.sap.dto.callback.SapCallbackRequest;
import com.deepexi.adapter.sdk.sap.dto.fund.SapFinalPaymentRequestBody;
import com.deepexi.adapter.sdk.sap.dto.fund.SapFundRequestBody;
import com.deepexi.adapter.sdk.sap.dto.fund.SapFundResponseBody;
import com.deepexi.adapter.sdk.sap.dto.fund.SapRefundRequestBody;
import com.deepexi.adapter.sdk.sap.dto.order.SapOrderRequestBody;
import com.deepexi.adapter.sdk.sap.dto.order.SapOrderResponseBody;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public class SapSdk {

    private static final Logger logger = LoggerFactory.getLogger(SapSdk.class);

    private SapSdkConfig sdkConfig;

    public SapSdk(String profile) {
        if (!"prod".equals(profile)) {
            logger.warn("非生产环境: sdk config, profile=" + profile);
        }
        this.sdkConfig = SapSdkConfig.fromResource(profile);
    }

    public SapSdk(String profile, String hostAddr, String name, String password) {
        this(profile);
        this.sdkConfig.setBaseAuthName(name);
        this.sdkConfig.setBaseAuthPassword(password);
        this.sdkConfig.setHostAddr(hostAddr);

        logger.info("sdkConfig {}", sdkConfig.beautify());

    }

    public SapSdk() {
        this("prod");
    }

    /** 发送 http请求 */
    public String doHttp(RequestInfo requestInfo) throws IOException, HttpNon200Exception {
        return HttpClientUtil.postJson4StringWithBaseAuth(
                requestInfo.url,
                requestInfo.strBody,
                this.sdkConfig.getBaseAuthName(),
                this.sdkConfig.getBaseAuthPassword());
    }

    /** 解析结果 */
    public <T> T parseResult(RequestInfo requestInfo, String result) throws JSONException {
        if (null == requestInfo) throw new RuntimeException("requestInfo null");

        SapApiType sapApiType = SapApiType.fromName(requestInfo.apiType);
        switch (sapApiType) {
            case BP:
            case SAP_BP_CREATE:
            case SAP_BP_EXTEND:
                return (T) ResponseParser.parseResult4BP(result);

            case ORDER:
                return (T) ResponseParser.parseResult4Order(result);

            case SAP_CALLBACK:
                return (T) ResponseParser.parseResult4Callback(result);

            case SAP_REFUND:
            case SAP_FUND:
            case SAP_FUND_FINAL_PAYMENT:
                return (T) ResponseParser.parseResult4Fund(result);
            default:
                throw new RuntimeException("不支持的api类型:" + sapApiType.name);
        }
    }

    /**
     * do http and parse string result to object
     *
     * @throws IOException   网络异常
     * @throws JSONException 解析异常
     */
    public <T> T doHttpAndParseResult(RequestInfo requestInfo) throws IOException, JSONException, HttpNon200Exception {
        String result = this.doHttp(requestInfo);
        return parseResult(requestInfo, result);
    }


    /** 回调接口 */
    public RequestInfo requestInfo4Callback(SapRecords<List<SapCallbackRequest>> body) {
        return new RequestInfo(
                "",
                sdkConfig.getHostAddr() + sdkConfig.getPath4Callback(),
                body.toString(),
                String.class,
                SapApiType.SAP_CALLBACK.name);
    }

    /** 资金接口 */
    public RequestInfo requestInfo4Fund(SapRecords<SapFundRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4Fund(),
                body.toString(),
                SapFundResponseBody.class,
                SapApiType.SAP_FUND.name);
    }

    /** 退款接口 */
    public RequestInfo requestInfo4Refund(SapRecords<SapRefundRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4Refund(),
                body.toString(),
                SapFundResponseBody.class,
                SapApiType.SAP_REFUND.name);
    }

    /** 尾款接口 */
    public RequestInfo requestInfo4FinalPayment(SapRecords<SapFinalPaymentRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4FundFinal(),
                body.toString(),
                SapFundResponseBody.class,
                SapApiType.SAP_FUND_FINAL_PAYMENT.name);
    }

    /** 新建 BP */
    public RequestInfo requestInfo4BPCreate(SapRecords<SapBPCreateRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4BP(),
                body.toString(),
                SapBPResponseBody.class,
                SapApiType.SAP_BP_CREATE.name);
    }

    /** 扩展 BP */
    public RequestInfo requestInfo4BPExtend(SapRecords<SapBPExtendRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4BP(),
                body.toString(),
                SapBPResponseBody.class,
                SapApiType.SAP_BP_EXTEND.name);
    }

    /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */

    /** 生成 ORDER 请求 */
    public RequestInfo requestInfo4Order(SapRecords<SapOrderRequestBody> body) {
        return new RequestInfo(
                body.getRecords().getReqId(),
                sdkConfig.getHostAddr() + sdkConfig.getPath4Order(),
                body.toString(),
                SapOrderResponseBody.class,
                SapApiType.ORDER.name);
    }

}
